/*
svn41
HappyFlags_7.pde Timer commands usually take a channel number and/or a time-value. 

Copyright (c) 2010 Ed Bennett.  All rights reserved. 

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

// The unit of time is is called a blink. The duration 
// of a blink is related to an AVR jiffy. See
// http://en.wikipedia.org/wiki/Jiffy_%28time%29

#include <TimerScheduler.h>

// hardware pins
int HF0 = 13;
int HF1 = 12;
int HF2 = 11;
int HF3 = 10;
int HF4 = 9;
int HF5 = 8;
int HF6 = 7;
int HF7 = 6;

int rate = 7;
int whichChannel = 0;
int randomize = 0;


int outval[8]={
  0,0,0,0,0,0,0,0};

int currentChannel;

void setup()
{   

  pinMode(HF0, OUTPUT); 
  pinMode(HF1, OUTPUT); 
  pinMode(HF2, OUTPUT);
  pinMode(HF3, OUTPUT); 
  pinMode(HF4, OUTPUT);
  pinMode(HF5, OUTPUT); 
  pinMode(HF6, OUTPUT);
  pinMode(HF7, OUTPUT); 

  Timer.attachPin(0, HF0);    // (channel, Ard. pin number)
  Timer.attachPin(1, HF1); 
  Timer.attachPin(2, HF2); 
  Timer.attachPin(3, HF3); 
  Timer.attachPin(4, HF4);

  // Register user's callback function names with their timer channels.
  Timer.onTick(5, setLowTime);   // (channelNumber, functionName)
  Timer.repeat(5, 1000);         // (channel, time)
  Timer.onTick(6, updatePinTimers); 
  Timer.repeat(6, 100); 
  Timer.onTick(7, randomMode);
  Timer.repeat(7, 3000);

  // Allow timers to be serviced in the timer interrupt
  Timer.start(0);    // happy flag 0
  Timer.start(1);    // happy flag 1
  Timer.start(2);    // happy flag 2
  Timer.start(3);    // happy flag 3
  Timer.start(4);    // happy flag 4
  Timer.start(5);    // ramps value of timer 6
  Timer.start(6);    // loads pin timer values -- master rate control
  Timer.start(7);    // randomizer-controller & print timer

  Timer.begin();     // start the hardware timer
  Serial.begin(1200);
}

/* 
 Timer 7 is being used with a callback, AND with its user flag. 
 The callback is fast, and the user-flag code in loop() uses
 Serial.print() which is slow. It's the best of both worlds running
 on Timer 7. The two pieces of code execute indepenant of each other.
 */

void loop()
{  
  if(Timer.flagIsSet(7)){ 
    Serial.print("How! High are you? ");
    Serial.println(whichChannel);
  }
}

// callback on timer 7
void randomMode(void){
  randomize ^=1; // toggle between sequential and random blink patterns
  digitalWrite(HF7, randomize); // random/sequential indicator lamp
}

// callback on timer 6
// updates one pin per call
void updatePinTimers(void){
  
  // HIGH TIME ramp factor- each new cycle is 90% of the previous
  // until the value is below 5
  outval[currentChannel]= outval[currentChannel] * 90/100;
  
  if(outval[currentChannel]< 5){
    outval[currentChannel]= 1000;
  } 
  

  // in a sequential blink pattern, currentChannel is the one 
  // we're doing now
  currentChannel++; 
  if(currentChannel >= 5){
    currentChannel=0;
  }
  whichChannel = currentChannel; // which channel to write

  // if randomize == 1, overwrite whichChannel with a random value 0-4
  if(randomize == 1){ 
    whichChannel = random(0,5);
  }

  // write the control value to fire the pin
  Timer.mono(whichChannel, outval[currentChannel]); 
}

// callback on timer 5
// This function ramps the repeat rate of Timer 6.
// (An example of one timer controlling another timer.)
// In this program, all timers have variable high times 
// but share the same value of low time. Timer 6 sets the 
// low time. Timer 5 modifies Timer 6 to ramp the blink 
// sequencing rate.
void setLowTime(void){  
  if(rate >300)rate=7;
  rate = rate * 100/85;
  Timer.repeat(6,rate);
}






